/*
 * com.jeach.stats - Created on Apr 9, 2007 6:38:07 PM
 *
 * Copyright (C) 2006 by Christian Jean.
 * All rights reserved.
 *
 * CONFIDENTIAL AND PROPRIETARY INFORMATION!
 *
 * Disclosure or use in part or in whole without prior written consent
 * constitutes an infringement of copyright laws which may be punishable
 * by law.
 *
 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
 * THE LICENSOR OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

package com.jeach.stats;

import org.apache.log4j.Logger;

import com.jeach.tools.JxRand;

/**
 * The <code>klass</code> class interface allows ...
 * 
 * @author Christian Jean (christian.jean@gmail.com)
 * @version 1.0
 * @since Apr 9, 2007 6:38:07 PM
 */
public class Stats {

	/** Log4J library */
	private static final Logger log = Logger.getLogger(Stats.class);

	/**
	 * Create a new <tt>DataSet</tt> instance populated with 'size' random
	 * values.
	 * <p>
	 * Each value will be between 0.0 (inclusive) and Double.MAX_VALUE
	 * (exclusive).
	 * 
	 * @param size
	 *            is the number of values to be created
	 * @return a <tt>DataSet</tt> instance
	 */
	public static DataSet getRandom(int size) {
		return getRandom(size, 0.0, Double.MAX_VALUE);
	}

	/**
	 * Create a new <tt>DataSet</tt> instance populated with 'size' random
	 * values.
	 * <p>
	 * Each value will be between 0.0 (inclusive) and 'max' value (exclusive).
	 * 
	 * @param size
	 *            is the number of values to be created
	 * @param max
	 *            the maximum value to use, greater than zero
	 * @return a <tt>DataSet</tt> instance
	 */
	public static DataSet getRandom(int size, double max) {
		return getRandom(size, 0.0, max);
	}

	/**
	 * Create a new <tt>DataSet</tt> instance populated with 'size' random
	 * values.
	 * <p>
	 * Each value will be between 0.0 (inclusive) and 'max' value (exclusive).
	 * 
	 * @param size
	 *            is the number of values to be created
	 * @param min
	 *            the minimum value to use, greater or equal to zero
	 * @param max
	 *            the maximum value to use, greater than min
	 * @return a <tt>DataSet</tt> instance
	 */
	public static DataSet getRandom(int size, double min, double max) {
		DataSet ds = null;

		log.debug("Getting a random data set!");
		log.debug(" o size = " + size);
		log.debug(" o min = " + min);
		log.debug(" o max = " + max);

		if (size == 0) {
			ds = new DataSet();
		} else if (size > 0) {
			ds = new DataSet();
			double val = 0.0;

			for (int i = 0; i < size; i++) {
				val = JxRand.getDouble(min, max);
				ds.addValue(new Value(val));
			}
		}

		return ds;
	}

	/**
	 * Creates a new sequential <tt>DataSet</tt> instance with the specified
	 * number of values starting at <tt>0.0</tt> and incrementing by
	 * <tt>0.1</tt> increments.
	 * 
	 * @param size
	 *            the number of values to be created
	 * @return a new <tt>DataSet</tt> instance
	 */
	public static DataSet getSequential(int size) {
		return getSequential(size, 0.0);
	}

	/**
	 * Creates a new sequential <tt>DataSet</tt> instance with the specified
	 * number of values starting at the specified value and incrementing by
	 * <tt>0.1</tt> increments.
	 * 
	 * @param size
	 *            the number of values to be created
	 * @param start
	 *            the starting value
	 * @return a new <tt>DataSet</tt> instance
	 */
	public static DataSet getSequential(int size, double start) {
		return getSequential(size, start, 0.1);
	}

	/**
	 * Creates a new sequential <tt>DataSet</tt> instance with the specified
	 * number of values starting and incrementing by the specified values.
	 * 
	 * @param size
	 *            the number of values to be created
	 * @param start
	 *            the starting value
	 * @param increment
	 *            the incrementing value
	 * @return a new <tt>DataSet</tt> instance
	 */
	public static DataSet getSequential(int size, double start, double increment) {
		DataSet ds = null;
		double value = start;

		log.debug("Getting a sequential data set!");
		log.debug(" o size = " + size);
		log.debug(" o start = " + start);
		log.debug(" o incr. = " + increment);

		if (size > 0) {
			ds = new DataSet();

			for (int i = 0; i < size; i++) {
				ds.addValue(new Value(value));
				value = value + increment;
			}
		}

		return ds;
	}

	/**
	 * Creates a new data set containing the specified number of values of the
	 * fibonacci sequence.
	 * <p>
	 * Leonardo of Pisa or Leonardo Pisano (c. 1175 - 1250), also known as
	 * Fibonacci, was an Italian mathematician and is best known for the
	 * invention of the Fibonacci numbers, and for his role in the introduction
	 * to Europe of the modern Arabic positional decimal system for writing and
	 * manipulating numbers (algorism).
	 * <p>
	 * A series of numbers created by adding the last two numbers in the series
	 * to produce the next number in the series, example: 1, 1, 2, 3, 5, 8, 13,
	 * 21, 34, 55, etc.
	 * <p>
	 * Successive numbers in the series relate to each other by the ratio .618
	 * or 1.618. This ratio has sometimes been called the golden ratio and
	 * underlines one methodology of analyzing the mathematical relationships
	 * between waves.
	 * 
	 * @param size
	 *            requests the number of values to add to data set
	 * @return a new <tt>DataSet</tt> instance holding fibonacci values
	 */
	public static DataSet getFibonacciSequence(int size) {
		DataSet ds = null;
		DataSet xx = null;

		log.debug("Getting a fibonacci data set!");
		log.debug(" o size = " + size);

		if (size > 0) {
			ds = new DataSet();

			for (int i = 1; i <= size; i++) {
				switch (i) {
				case 1:
					ds.addValue(0.0);
					break;
				case 2:
					ds.addValue(1.0);
					break;
				default:
					xx = ds.getLast(2);
					log.debug("Last 2 values: " + xx.printValues());
					ds.addValue(xx.getSummation());
					break;
				}
			}
		}

		return ds;
	}
}
